package com.example.myapplication1.publishFriendCircle;

import android.content.Context;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.RecyclerView;

import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * Created by superchen on 2017/6/20.
 */
public abstract class ItemTouchAdapter<T, VH extends RecyclerView.ViewHolder> extends RecyclerView.Adapter<VH> implements
        ItemTouchHelperAdapter<T> {

    private WeakReference<Context> mWeakContext;
    protected List<T> mData;
    protected List<Integer> mCannotMovePositionList;
    protected RecyclerView.AdapterDataObserver mObserver = new RecyclerView.AdapterDataObserver() {
        @Override
        public void onChanged() {
            super.onChanged();
            notifyChanged();
        }

        @Override
        public void onItemRangeChanged(int positionStart, int itemCount) {
            super.onItemRangeChanged(positionStart, itemCount);
            onChanged();
        }

        @Override
        public void onItemRangeChanged(int positionStart, int itemCount, @Nullable Object payload) {
            super.onItemRangeChanged(positionStart, itemCount, payload);
            onChanged();
        }

        @Override
        public void onItemRangeInserted(int positionStart, int itemCount) {
            super.onItemRangeInserted(positionStart, itemCount);
            onChanged();
        }

        @Override
        public void onItemRangeRemoved(int positionStart, int itemCount) {
            super.onItemRangeRemoved(positionStart, itemCount);
            onChanged();
        }

        @Override
        public void onItemRangeMoved(int fromPosition, int toPosition, int itemCount) {
            super.onItemRangeMoved(fromPosition, toPosition, itemCount);
            onChanged();
        }
    };

    public ItemTouchAdapter(@NonNull Context context) {
        mWeakContext = new WeakReference<>(context);
        registerAdapterDataObserver(mObserver);
    }

    @Nullable
    @Override
    public Context getContext() {
        return mWeakContext != null ? mWeakContext.get() : null;
    }

    @Override
    public boolean onItemMove(int fromPosition, int toPosition) {
        if (fromPosition < toPosition) {
            for (int i = fromPosition; i < toPosition; i++) {
                Collections.swap(getData(), i, i + 1);
            }
        } else {
            for (int i = fromPosition; i > toPosition; i--) {
                Collections.swap(getData(), i, i - 1);
            }
        }
        notifyItemMoved(fromPosition, toPosition);
        return true;
    }

    @Override
    public boolean onItemRemove(int position) {
        if (mData != null && position >= 0 && position < mData.size()) {
            mData.remove(position);
            notifyItemRemoved(position);
            notifyItemRangeChanged(0, getItemCount());
        }
        return true;
    }

    @NonNull
    @Override
    public List<T> getData() {
        return mData == null ? mData = new ArrayList<>() : mData;
    }

    @Override
    public List<Integer> getCannotDragIndexList() {
        return mCannotMovePositionList;
    }

    public int getDataCount() {
        return mData == null ? 0 : mData.size();
    }

    protected void notifyChanged() {
    }

    @Nullable
    public T getItem(int position) {
        return mData != null && position >= 0 && position < mData.size() ? mData.get(position) : null;
    }

    public void setData(List<T> data) {
        this.mData = data;
    }

    public void addItem(T item) {
        if (item == null) return;
        if (mData == null) {
            mData = new ArrayList<>();
        }
        mData.add(item);
    }

    public void removeItem(int position) {
        if (position >= 0 && position < getDataCount()) {
            mData.remove(position);
        }
    }

    public void removeItem(T item) {
        mData.remove(item);
        notifyDataSetChanged();
    }

    public void destroy() {
        mData = null;
        unregisterAdapterDataObserver(mObserver);
        mObserver = null;
        mWeakContext = null;
    }
}
